/* simple implement for intrusive list */
#ifndef _Z_LIST_H_
#define _Z_LIST_H_

#ifdef __cplusplus
extern "C" {
#endif

typedef unsigned long size_t;

struct list_head {
	struct list_head *prev, *next;
};
#ifdef z_offsetof
#undef z_offsetof
#endif
typedef long ssize_t;
#define z_offsetof(type,member)\
	((ssize_t) &(((type *)0)->member))

#define container_of(ptr,type,member)\
		((type *)((char *)ptr - z_offsetof(type,member)))

/*For entry*/
#define __list_entry(ptr,type,member) container_of(ptr,type,member)

#define init_list(name) struct list_head name = {&(name),&(name)}

//#define new_node(name) struct list_head name = {NULL,NULL}
struct list_head * new_list_head(); 
void free_list_head(struct list_head * head);

int list_empty(const struct list_head *head);

size_t list_length(const struct list_head *head);

void __list_add(struct list_head *node, struct list_head *prev,
		struct list_head *next);
/*For entry*/
#define ____list_add_entry(entry,prev,next,member) \
	__list_add(&(entry)->member,&(prev)->member,&(next)->member)

void list_add(struct list_head *head, struct list_head *node);

void list_add_tail(struct list_head *head, struct list_head *node);
/*For entry*/
#define __list_add_entry(head,entry,member) \
	list_add(head,&(entry)->member)

/*For stack and queue*/
#define list_push(head,node) list_add(head,node)
#define __list_push_entry(head,entry,member) list_add(head,&(entry->member))
#define list_enqueue(head,node) list_add_tail(head,node)
#define __list_enqueue_entry(head,entry,member) list_add_tail(head,&(entry->member))

struct list_head * __list_del(struct list_head *prev, struct list_head *next);

struct list_head * list_del(struct list_head *head) ;

/*For stack and queue*/
#define list_pop(head) list_del(head)
#define __list_pop_entry(head,type,member) __list_entry((list_pop(head)),type,member)
#define list_dequeue(head) list_del(head)
#define __list_dequeue_entry(head,type,member) __list_entry((list_pop(head)),type,member)

#define list_foreach(head,itr) \
	for (struct list_head *itr = head->next; \
			itr != head; itr = itr->next)
#define list_foreach_prev(head,itr) \
	for (struct list_head *itr = head->prev; \
			itr != head; itr = itr->prev)
/*A safe implement for deleting node(s) at travel*/
#define list_foreach_safe(head,itr) \
	for (struct list_head *itr = head->next,*tmp_itr; \
			(tmp_itr = itr->next)&&(itr != head); \
			itr = tmp_itr)
#define list_foreach_prev_safe(head,itr) \
	for (struct list_head *itr = head->next,*tmp_itr; \
			(tmp_itr = itr->prev)&&(itr != head); \
			itr = tmp_itr)

/*For entry*/
#define __list_foreach_entry(head,type,member,itr) \
	for (type *itr = __list_entry(head->next,type,member); \
			&itr->member != head; \
			itr = __list_entry(itr->member.next,type,member))

#define __list_foreach_entry_reverse(head,type,member,itr) \
	for (type *itr = __list_entry(head->prev,type,member); \
			&itr->member != head; \
			itr = __list_entry(itr->member.prev,type,member))

/*Iterator of entry*/
#define __list_next_entry(head,entry,type,member) (((entry)->member.next != head)? \
																	__list_entry((entry)->member.next,type,member) : \
																	__list_entry((entry)->member.next->next,type,member))
#define __list_prev_entry(head,entry,type,member) (((entry)->member.prev != head)? \
																	__list_entry((entry)->member.prev,type,member) : \
																	__list_entry((entry)->member.prev->prev,type,member)) 

/*Utils*/
#if defined(ENTRY_TYPE) && defined(ENTRY_MEMBER)
#warning "macro ENTRY_TYPE and ENTRY_MEMBER have been defined, \
	 make sure these are defined by yourself.\
	That's mean you can use the simplify version macros"

	#define list_entry(ptr) \
			__list_entry(ptr,ENTRY_TYPE,ENTRY_MEMBER)
	#define list_foreach_entry(head,itr) \
			__list_foreach_entry(head,ENTRY_TYPE,ENTRY_MEMBER,itr)
	#define list_foreach_entry_reverse(head,itr) \
			__list_foreach_entry_reverse(head,ENTRY_TYPE,ENTRY_MEMBER,itr)

	#define list_add_entry(head,entry) 		__list_add_entry(head,entry,ENTRY_MEMBER)
	#define list_push_entry(head,entry) 	__list_add_entry(head,entry,ENTRY_MEMBER)
	#define list_enqueue_entry(head,entry) 	__list_enqueue_entry(head,entry,ENTRY_MEMBER)
	#define list_pop_entry(head) 			__list_pop_entry(head,ENTRY_TYPE,ENTRY_MEMBER)
	#define list_dequeue_entry(head) 		__list_dequeue(head,ENTRY_TYPE,ENTRY_MEMBER)

	#define list_prev_entry(head,entry) 	__list_prev_entry(head,entry,ENTRY_TYPE,ENTRY_MEMBER)
	#define list_next_entry(head,entry) 	__list_next_entry(head,entry,ENTRY_TYPE,ENTRY_MEMBER)

#else

	#define list_entry  			__list_entry
	#define list_foreach_entry 		__list_foreach_entry
    #define list_foreach_entry_reverse 		__list_foreach_entry_reverse

	#define list_add_entry 			__list_add_entry
	#define list_push_entry 		__list_add_entry
	#define list_enqueue_entry 		__list_enqueue_entry
	#define list_pop_entry 			__list_pop_entry
	#define list_dequeue_entry 		__list_dequeue_entry

	#define list_prev_entry 		__list_prev_entry
	#define list_next_entry 		__list_next_entry

#endif
#ifdef __cplusplus
}
#endif
#endif
